from __future__ import with_statement # needed for python 2.5
from fabric.api import *
from fabric.contrib import files, console
from fabric import context_managers
from uc_deploy.uc_utilities import *
from uc_deploy.uc_utilities import _file_read
from uc_deploy.uc_utilities import _locate_program
from uc_deploy.uc_utilities import _file_ensure_append
from uc_deploy.uc_utilities import _file_ensure
#from uc_deploy.uc_templates import *

#===============================================================================
# uc_wrapper.py
#
# Author: Created by Christopher Steel
# 
# Organization_EN : Voice of Access
# Organization_FR : voix d'acces
#
# License : The MIT License Copyright (c) 2011 Voice of Access
#
# Description: uc_wrappers is a Universal Cake* fabric module for manipulating
# virtual environments created using virtualenvwrapper.sh
#
# Universal Cake : Software created by Voice of Access and designated as 
# "Universal Cake" via the usage of the prefix "uc" has been created to insure
# for very high levels of usability and accessibility both now and in the future.
#
# Requirements: Fabric, uc_utilities.py
#===============================================================================

## VIRTUALENVWRAPPER
#
def envs_collection_remove(envs_name=None):
    '''
    Remove the default collection of virtual environments
    or the collection of virtual environments specified 
    with envs_name.
    '''
    require('env.target_envs', provided_by=('dev', 'prod'))
    if envs_name!=None:
        env.env.target_envs = envs_name
    print('current envs directory is %(env.target_envs)s' %env)
    if not os.path.isfile(env.env.target_envs):
        run('rm -R  %(env.target_envs)s' % env)

def _envs_collection_create(envs_name):
    '''
    Create dir holding our default collection of virtual environments
    or the dir specified via envs_name
    '''
    require('env.target_envs', provided_by=('dev', 'prod'))
    if envs_name!=None:
        env.env.target_envs = envs_name
    print('current envs directory is %(env.target_envs)s' %env)
    if not os.path.isfile(env.env.target_envs):
        run('mkdir -p %(env.target_envs)s' % env)

def _virtualenvwrapper_config():
    '''
    Configure target to use virtualenvwrapper.sh

    We can recreate this file each time this function is run...
    '''
    print('### check for startup_file')
    if not files.exists(env.startup_file):
        print ('PLEASE CONFIGURE env.startup_file !!!')
    else:
        # BACKUP OLD WRAPPER CONFIG FILE
        if files.exists(env.wrapper_config):
            print('moving old wrapper config so it does not get clobbered')
#######################
            env.wrapper_config_backup = os.path.join(env.wrapper_config + '_' + env.timestamp)
            run('mv %(wrapper_config)s %(wrapper_config_backup)s' % env)
        run('touch %(wrapper_config)s' % env)
        # CONFIGURE STARTUP FILE TO SOURCE WRAPPER CONFIG
        print('### append source to startup')
        append_source = run("echo 'source %(wrapper_config)s'"% env)
        _file_ensure_append(env.startup_file, append_source)
        # APPEND EXPORT WORKON_HOME TO WRAPPER_CONFIG
        print('### append export')
        append_export = run("echo 'export WORKON_HOME=%(envs)s'"% env)
        _file_ensure_append(env.wrapper_config, append_export)
        location =_locate_program('virtualenvwrapper.sh')
        append_wrapper_source = run("echo 'source %s'" % (location))
        _file_ensure_append(env.wrapper_config, append_wrapper_source)
        _envs_collection_create(env.envs)

def env_create(env=None):
    '''
    ## 1 - fab dev env_create
    create a new virtualenv using virtualenvwrapper if none with
    the requested name exists.

    Usage Examples:
        command line:
            fab dev env_create
            fab dev env_create:my_virtual_environment
        call:
                env_create(my_virtual_environment)
    '''
    _virtualenvwrapper_config()
    if not files.exists(env.target_env):
        prefix = run('echo "source %(wrapper_config)s"' % env)
        args = '--no-site-packages'
        env_name = os.path.basename(env.target_env)
        with cd(env.envs):
#            run('%s && mkvirtualenv %s %s' % (prefix,args,env_name))
             print('run mkvirtualenv')
    print('virtualenv exists')
#    env_launcher_create()


def launcher():
    '''
    ## 2 ??? fab dev launcher
    '''
    upload_fabric_template(env.tp_w2p_launch_src_path,env.tp_w2p_launch_target)
#    upload_template(filename=env.tp_w2p_launch_src,
#                    destination=env.tp_w2p_launch_target,
#                    context=None,
#                    use_jinja=False,
#                    template_dir=None,
#                    use_sudo = False)
    sudo('chmod 755 %(tp_w2p_launch_target)s' %env)
    run('cat %(tp_w2p_launch_target)s' %env)


def env_launcher_create(app='web2py'):
    '''
    ## 4 - fab dev env_launcher_create
    Create a python application launcher for the current virtual
    environment

    Usage Example:

    fab dev env_launcher_create():
    
    # our target launch script
    python web2py.py -a test -p 8000&
    echo $! > PID.TXT&
    sleep 2
    open -a /Applications/Firefox.app/Contents/MacOS/firefox-bin http://127.0.0.1:8000/&
    
    # our target kill script
    pid=`cat PID.TXT`
    kill -KILL $pid
    '''
    env.current_w2p_launcher_name = 'launch_%s_%s.sh'% (env.project_name, app)
    env.current_w2p_launcher = os.path.join(env.webapps, env.current_w2p_launcher_name)
    run('touch %(current_w2p_launcher)s' % env)
#    run ('echo "%(env_python)s %(w2p_bin)s" > %(current_w2p_launcher)s' % env
#    run('pwd')
    run ('cat "%(w2p_pid)s" > %(current_w2p_launcher)s' % env)
#    run ('echo "kill -SIGTERM $pid" >> %(current_w2p_launcher)s' % env)
    run ('echo "%(env_python)s %(w2p_bin)s %(w2p_start_opts)s" >> %(current_w2p_launcher)s' % env)
    run ('echo "echo $! > PID.TXT&" >> %(current_w2p_launcher)s' % env)
    run ('echo "sleep 3" >> %(current_w2p_launcher)s' % env)
    run ('echo "open -a /Applications/Firefox.app/Contents/MacOS/firefox-bin http://127.0.0.1:8000/&" >> %(current_w2p_launcher)s' % env)
    run('chmod +x %(current_w2p_launcher)s'% env)

def env_remove(env_name=None):
    '''
    Remove the currently selected virtualenv and containing directory
    or will attempt to do if the name of a specific virtual environment
    is passed to the function.

    TODO : Add option all ?

    Usage Examples:
        command line:
            fab devment env_remove
            fab devment env_remove:my_virtual_environment
        call:
                env_remove(my_virtual_environment)
    '''
    if env_name==None:
        print('current selected env is %(target_env)s' %env)
    else:
        env.target_env = os.path.join(env.envs, env_name)
        print('current selected env is %(target_env)s' %env)
    require('wrapper', provided_by=('devment', 'prod'))
    run('%(wrapper)s rmvirtualenv %(target_env)s' % env)
    run('rm -R %(target_env)s' % env)

def env_pip_install(env_app='mercurial', env_name=None):
    '''
    ## 2 - fab dev env_pip_install:mercurial
    pip install to target_env variable unless another valid
    env is specified.

    Ubuntu requires : sudo apt-get install python-dev
    '''
    require('target_env', provided_by=('devment', 'prod'))
    if env_name==None:
        print('current selected env is %(target_env)s' %env)
        env.target_env = env.env
    else:
        env.target_env = os.path.join(env.envs, env_name)
        print('current selected env is %(target_env)s' %env)
    env_name = os.path.basename(env.target_env)
    if not files.exists(env.target_env):
        print('%(target_env)s does not exists' % env)
    else:
        if env_app == 'mercurial':
            env.hg_bin = os.path.join(env.target_env, 'bin','hg')
            if not files.exists(env.hg_bin):
                with cd(env.env.target_envs):
                    env.pip_bin = os.path.join(env.target_env, 'bin','pip')
                    run('%s install %s' % (env.pip_bin, env_app))
                    env.hg_bin = os.path.join(env.target_env, 'bin','hg')
            hg_ver = run('%(hg_bin)s --version' % env)
            print('virtualenv have following Mercurial')
            print(hg_ver)
        if env_app == 'lxml':
            with cd(env.env.target_envs):
                env.pip_bin = os.path.join(env.target_env, 'bin','pip')
                run('echo "STATIC_DEPS=true"')
                run('%s install %s' % (env.pip_bin, env_app))
        else:
            print('installind of %s not supported at this time' %(env_app))
